home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’95
/
Menu Controls
/
ShapeCommands.cp
< prev
next >
Wrap
Text File
|
1995-06-24
|
49KB
|
1,571 lines
// Copyright © 1994-95 by Apple Computer, Inc. All rights reserved.
// ShapeCommands.cp
#ifndef __SHAPECOMMANDS__
#include "ShapeCommands.h"
#endif
// MacApp
#ifndef __UFAILURE__
#include <UFailure.h>
#endif
#ifndef __UCLIPBOARDMGR__
#include <UClipboardMgr.h>
#endif
#ifndef __UMEMORY__
#include <UMemory.h>
#endif
#ifndef __UWINDOW__
#include <UWindow.h>
#endif
#ifndef __UMACAPPUTILITIES__
#include <UMacAppUtilities.h>
#endif
// DrawShapes
#ifndef __PATTERNMENU__
#include "PatternMenu.h"
#endif
#ifndef __UDRAWSHAPES__
#include "UDrawShapes.h"
#endif
#ifndef __UPICTSHAPE__
#include "UPictShape.h"
#endif
#ifndef __USHAPESDOCUMENT__
#include "UShapesDocument.h"
#endif
#ifndef __USHAPEVIEW__
#include "UShapeView.h"
#endif
#ifndef __UTEXTSHAPE__
#include "UTextShape.h"
#endif
//--------------------------------------------------------------------------------------------------
// More Constants
// Minimum height and width of new shapes
#define kMinHeight 20
#define kMinWidth 20
CPoint gClipMargin(16,16); // the top & left margins to use when
// displaying shapes in the Clipboard
//========================================================================================
// Functions and structs used by EachVirtualShapeDo and EachNewShapeDo
// typedef void(* DoToShapeType)(TShape* item, void* staticLink);
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void BeInvalidated(TShape* shape, void* staticLink)
{
// staticLink is really a TShapeView*
TShapeView* shapeView = (TShapeView*)staticLink;
shapeView->InvalShape(shape);
}
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void BeSelected(TShape* shape, void* staticLink)
{
// staticLink is really a TShapeView*
TShapeView* shapeView = (TShapeView*)staticLink;
shape->SetSelected(true);
shapeView->InvalShape(shape);
}
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void EraseShape(TShape* shape, void* staticLink)
{
// staticLink is really a TShapeView*
TShapeView* shapeView = (TShapeView*)staticLink;
if (shape->IsSelected())
shapeView->InvalShape(shape);
}
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void HandleIt(TShape* shape, void* staticLink)
{
// staticLink is really a TShapeDocument*
TShapeDocument* shapeDocument = (TShapeDocument*)staticLink;
if (shape->WasSelected())
shapeDocument->DeleteShape(shape);
}
//----------------------------------------------------------------------------------------
struct HighlightRec
{
CRect& fBounds;
TShapeView* fShapeView;
HighlightRec(CRect& bounds, TShapeView* shapeView);
};
#pragma segment ADoCommand
HighlightRec::HighlightRec(CRect& bounds, TShapeView* shapeView) :
fBounds(bounds),
fShapeView(shapeView)
{
}
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void HighlightShape(TShape* shape, void* staticLink)
{
// staticLink is really a HighlightRec*
HighlightRec* hlRecPtr = (HighlightRec*)staticLink;
CRect extent;
shape->GetFrame(extent);
if (RectsNest(hlRecPtr->fBounds, extent))
{
if (shape->IsSelected())
shape->Highlight(hlOn, hlOff, hlRecPtr->fShapeView);
else
shape->Highlight(hlOff, hlOn, hlRecPtr->fShapeView);
shape->SetSelected(!shape->IsSelected());
}
}
//========================================================================================
// CLASS TShapeCommand
//========================================================================================
#undef Inherited
#define Inherited TBetterFeedbackCmd
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeCommand, Inherited);
//----------------------------------------------------------------------------------------
// TShapeCommand Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeCommand::TShapeCommand()
{
fShapeView = NULL;
fShapeDocument = NULL;
}
//----------------------------------------------------------------------------------------
// TShapeCommand::IShapeCommand
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeCommand::IShapeCommand(CommandNumber itsCommandNumber,
TShapeView* itsShapeView,
Boolean canUndo,
Boolean causesChange,
const VPoint& theMouse,
Boolean betterFeedbackDesired)
{
this->IBetterFeedbackCmd(itsCommandNumber,
itsShapeView->fShapeDocument,
canUndo,
causesChange,
itsShapeView->fShapeDocument,
itsShapeView,
itsShapeView->GetScroller(FALSE),
theMouse,
betterFeedbackDesired);
fShapeView = itsShapeView;
fShapeDocument = itsShapeView->fShapeDocument;
}
//========================================================================================
// CLASS TShapeSelector
//========================================================================================
#undef Inherited
#define Inherited TShapeCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeSelector, Inherited);
//----------------------------------------------------------------------------------------
// TShapeSelector Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeSelector::TShapeSelector()
{
fLastMarch = 0;
fBounds = gZeroRect;
fShiftKey = false;
}
//----------------------------------------------------------------------------------------
// TShapeSelector::IShapeSelector
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeSelector::IShapeSelector(CommandNumber itsCommandNumber,
TShapeView* itsShapeView,
const VPoint& theMouse)
{
this->IShapeCommand(itsCommandNumber,
itsShapeView,
kCantUndo,
kDoesNotCauseChange,
theMouse,
gBetterFeedback);
CStr255 hexString = "7C3E1F8FC7E3F1F8";
StuffHex(&fAnts, hexString);
}
//----------------------------------------------------------------------------------------
// TShapeSelector::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSelector::DoIt() // Override
{
HighlightRec hlRec(fBounds, fShapeView);
fShapeDocument->EachVirtualShapeDo(&HighlightShape, (void*)&hlRec);
}
//----------------------------------------------------------------------------------------
// TShapeSelector::TrackFeedback
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSelector::TrackFeedback(TrackPhase aTrackPhase,
const VPoint& anchorPoint,
const VPoint& previousPoint,
const VPoint& nextPoint,
Boolean mouseDidMove,
Boolean turnItOn) // Override
{
Inherited::TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint,
mouseDidMove, turnItOn);
CRect r;
Pt2Rect(fView->ViewToQDPt(anchorPoint), fView->ViewToQDPt(nextPoint), r);
switch (aTrackPhase)
{
case trackBegin:
case trackEnd:
PenPat(&fAnts);
FrameRect(r); // draw/Erase
break;
case trackContinue:
if (turnItOn)
{
if (mouseDidMove)
{
PenPat(&fAnts);
FrameRect(r);
}
else if (TickCount() - fLastMarch >= 4)
{
Pattern oldPat = fAnts;
RotatePat(fAnts);
Pattern diffPat;
XorPat(oldPat, fAnts, diffPat);
PenPat(&diffPat);
FrameRect(r); // march
fLastMarch = TickCount();
}
}
else
{
if (mouseDidMove)
{
PenPat(&fAnts);
FrameRect(r); // erase
}
}
break;
}
}
//----------------------------------------------------------------------------------------
// TShapeSelector::TrackMouse
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
TTracker* TShapeSelector::TrackMouse(TrackPhase aTrackPhase,
VPoint& anchorPoint,
VPoint& previousPoint,
VPoint& nextPoint,
Boolean mouseDidMove) // Override
{
TTracker* newTracker = Inherited::TrackMouse(aTrackPhase, anchorPoint, previousPoint,
nextPoint, mouseDidMove);
CRect r;
CPoint qdAnchor = fShapeView->ViewToQDPt(anchorPoint);
CPoint qdPrevious = fShapeView->ViewToQDPt(previousPoint);
Pt2Rect(qdAnchor, qdPrevious, r);
fBounds = r;
return newTracker;
}
//========================================================================================
// CLASS TShapeDragger
//========================================================================================
#undef Inherited
#define Inherited TShapeCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeDragger, Inherited);
//----------------------------------------------------------------------------------------
// TShapeDragger Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeDragger::TShapeDragger()
{
fBounds = gZeroRect;
fDeltaH = 0;
fDeltaV = 0;
}
//----------------------------------------------------------------------------------------
// TShapeDragger::IShapeDragger
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeDragger::IShapeDragger(TShapeView* itsShapeView,
const VPoint& theMouse)
{
this->IShapeCommand(cMoveShape, itsShapeView, kCanUndo, kCausesChange,
theMouse, gBetterFeedback);
CRect bounds;
short numberOfShapes;
fShapeDocument->SurveyShapes(true, numberOfShapes, bounds);
itsShapeView->SetDragging(false);
fBounds = bounds;
fConstrainsMouse = gConstrainDrags;
}
//----------------------------------------------------------------------------------------
// TShapeDragger::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeDragger::DoIt() // Override
{
this->MoveBy(fDeltaH, fDeltaV);
}
//----------------------------------------------------------------------------------------
// TShapeDragger::MoveBy
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeDragger::MoveBy(long deltaH, long deltaV)
{
fShapeView->Focus();
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->IsSelected())
{
CRect extent;
shape->GetFrame(extent);
OffsetRect(extent, (short)deltaH, (short)deltaV);
shape->SetFrame(extent);
fShapeView->InvalShape(shape);
}
shape->SetWasSelected(shape->IsSelected());
}
}
//----------------------------------------------------------------------------------------
// TShapeDragger::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeDragger::RedoIt() // Override
{
fShapeView->RestoreSelection();
this->MoveBy(fDeltaH, fDeltaV);
}
//----------------------------------------------------------------------------------------
// TShapeDragger::TrackConstrain
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeDragger::TrackConstrain(TrackPhase /*aTrackPhase*/,
const VPoint& anchorPoint,
const VPoint& /*previousPoint*/,
VPoint& nextPoint,
Boolean /*mouseDidMove*/) // Override
{
for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
{
VCoordinate temp = anchorPoint[vhs] - fBounds[topLeft][vhs];
nextPoint[vhs] = Max(temp, nextPoint[vhs]);
temp = fShapeView->fSize[vhs] - (fBounds[botRight][vhs] - anchorPoint[vhs]);
nextPoint[vhs] = Min(temp, nextPoint[vhs]);
}
}
//----------------------------------------------------------------------------------------
// TShapeDragger::TrackFeedback
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeDragger::TrackFeedback(TrackPhase aTrackPhase,
const VPoint& anchorPoint,
const VPoint& previousPoint,
const VPoint& nextPoint,
Boolean mouseDidMove,
Boolean turnItOn) // Override
{
Inherited::TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint,
mouseDidMove, turnItOn);
if (mouseDidMove && fShapeView->IsDragging())
{
CPoint delta;
delta.h = (short) (nextPoint.h - anchorPoint.h);
delta.v = (short) (nextPoint.v - anchorPoint.v);
CRect aRect(fBounds);
OffsetRect(aRect, delta.h, delta.v);
FrameRect(aRect); // draw/erase it
}
}
//----------------------------------------------------------------------------------------
// TShapeDragger::TrackMouse
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
TTracker* TShapeDragger::TrackMouse(TrackPhase aTrackPhase,
VPoint& anchorPoint,
VPoint& previousPoint,
VPoint& nextPoint,
Boolean mouseDidMove) // Override
{
TTracker* newTracker = Inherited::TrackMouse(aTrackPhase, anchorPoint, previousPoint,
nextPoint, mouseDidMove);
if (aTrackPhase == trackRelease)
{
if (fShapeView->IsDragging())
{
fDeltaH = previousPoint.h - anchorPoint.h;
fDeltaV = previousPoint.v - anchorPoint.v;
fShapeView->SetDragging(false);
}
else
newTracker = NULL;
}
else if (aTrackPhase == trackMove)
{
if (mouseDidMove)
if (!fShapeView->IsDragging()) // this is first move
{
fShapeView->DoHighlightSelection(hlOn, hlOff);
fShapeDocument->EachVirtualShapeDo(&EraseShape, (void*)fShapeView);
fShapeView->SetDragging(true);
fShapeView->GetWindow()->Update(); // ???
fShapeView->Focus(); // UpdateEvent changes the focus - restore it
}
}
return newTracker;
}
//----------------------------------------------------------------------------------------
// TShapeDragger::UndoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeDragger::UndoIt() // Override
{
fShapeView->RestoreSelection();
this->MoveBy(-fDeltaH, -fDeltaV);
}
//========================================================================================
// CLASS TReshadeCmd
//========================================================================================
#undef Inherited
#define Inherited TTearOffMenuViewTracker
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TReshadeCmd, Inherited);
//----------------------------------------------------------------------------------------
// TReshadeCmd Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TReshadeCmd::TReshadeCmd()
{
fShapeView = NULL;
fShapeDocument = NULL;
fPattern = 0;
fExitTracking = false;
fMenuPatternsPalette = NULL;
fFloatingPatternsPalette = NULL;
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::IReshadeCmd
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TReshadeCmd::IReshadeCmd(CommandNumber itsCommandNumber,
TShapeView* itsShapeView,
TPatternsPalette* thePatternsPalette,
TPatternsPalette* menuPatternsPalette,
TPatternsPalette* floatingPatternsPalette,
const VPoint& theMouse)
// thePatternsPalette is the view we're tracking in
// floatingPatternsPalette is the view that's in the floating window
{
TDocument* doc = NULL;
if (itsShapeView)
doc = itsShapeView->fDocument;
this->ITearOffMenuViewTracker(cChangeShade, doc, kCanUndo, kCausesChange, doc,
thePatternsPalette, NULL, theMouse);
fShapeView = itsShapeView;
fShapeDocument = itsShapeView->fShapeDocument;
fMenuPatternsPalette = menuPatternsPalette;
fFloatingPatternsPalette = floatingPatternsPalette;
fPattern = (short) (itsCommandNumber - cPatterns);
fViewConstrain = false;
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::TrackMouse
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
TTracker* TReshadeCmd::TrackMouse(TrackPhase aTrackPhase,
VPoint& /*anchorPoint*/,
VPoint& /*previousPoint*/,
VPoint& nextPoint,
Boolean /*mouseDidMove*/) // Override
{
TTracker* newTracker = this;
if (gTrackingInMenu)
{
/* quit tracking when the mouse leaves the view
- if gTrackingInMenu is TRUE, view constrain is set to FALSE, so nextPoint CAN leave the view
- all other times, view constrain is TRUE, so nextPoint WON'T leave the view
*/
if (fView && fView->IsShown())
fExitTracking = !fView->ContainsMouse(nextPoint);
/* if gTrackingInMenu is TRUE, then fExitTracking might get set to TRUE above, meaning
that the user is either returning to the menubar or trying to tear off this
menu, so simply return NULL when we're done tracking and the tracker will be freed
by TApplication::TrackMouse.
*/
if ((aTrackPhase == trackRelease) && fExitTracking)
newTracker = NULL;
}
return newTracker;
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::TrackFeedback
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TReshadeCmd::TrackFeedback(TrackPhase aTrackPhase,
const VPoint& anchorPoint,
const VPoint& previousPoint,
const VPoint& nextPoint,
Boolean mouseDidMove,
Boolean turnItOn) // Override
{
// All we really want to do here is let the view give us some feedback, so...
if (fView && fView->IsShown() && mouseDidMove)
fView->TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint, mouseDidMove, turnItOn);
/* When we're selecting a pattern (i.e. turning it on) then this command needs to know
about the new selection. When we're deselecting a pattern (i.e. turning it off) then this
command MUST ignore the deselection since MacApp's tracking will turn off the current
selection as part of its default tracking behavior even when the user has made a valid
selection in the view.
*/
if (turnItOn)
fPattern = ((TPatternsPalette*)fView)->fSelectedPattern;
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::IsDoneTracking
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
Boolean TReshadeCmd::IsDoneTracking() // Override
{
return !StillDown() || fExitTracking;
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TReshadeCmd::DoIt() // Override
{
// tell the patterns view in the menu which pattern is selected
if (fMenuPatternsPalette)
{
fMenuPatternsPalette->fOldPattern = fMenuPatternsPalette->fCurrPattern;
fMenuPatternsPalette->fCurrPattern = fPattern;
}
// tell the floating window which pattern is selected
if (fFloatingPatternsPalette)
{
fFloatingPatternsPalette->fOldPattern = fFloatingPatternsPalette->fCurrPattern;
fFloatingPatternsPalette->SelectNewPattern(fPattern);
}
if (fShapeDocument)
{
if (fShapeView)
fShapeView->Focus();
/* fShapeDocument.EachShapeDo(ReshadeShape); */
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->IsSelected())
{
shape->ReplacePattern(fPattern);
fShapeView->InvalShape(shape);
}
shape->SetWasIsSelected();
}
}
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TReshadeCmd::RedoIt() // Override
{
// tell the floating window which pattern is selected
if (fFloatingPatternsPalette)
fFloatingPatternsPalette->SelectNewPattern(fPattern);
if (fShapeView)
{
fShapeView->Focus();
fShapeView->Deselect();
/* fShapeDocument.EachShapeDo(ReshadeShape); */
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->WasSelected())
{
shape->ReplacePattern(fPattern);
fShapeView->InvalShape(shape);
}
shape->SetIsWasSelected();
}
}
}
//----------------------------------------------------------------------------------------
// TReshadeCmd::UndoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TReshadeCmd::UndoIt() // Override
{
// tell the floating window which pattern *was* selected
if (fFloatingPatternsPalette)
fFloatingPatternsPalette->SelectNewPattern(fFloatingPatternsPalette->fOldPattern);
if (fShapeView)
{
fShapeView->Focus();
fShapeView->Deselect();
/* fShapeDocument.EachShapeDo(ReshadeShape); */
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->WasSelected())
{
shape->fPattern = shape->fOldPattern;
fShapeView->InvalShape(shape);
}
shape->SetIsWasSelected();
}
}
}
//========================================================================================
// CLASS TRecolorCmd
//========================================================================================
#undef Inherited
#define Inherited TShapeCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TRecolorCmd, Inherited);
//----------------------------------------------------------------------------------------
// TRecolorCmd Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TRecolorCmd::TRecolorCmd()
{
fColor = gRGBBlack;
}
//----------------------------------------------------------------------------------------
// TRecolorCmd::IRecolorCmd
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TRecolorCmd::IRecolorCmd(CRGBColor itsColor, TShapeView* itsShapeView)
{
this->IShapeCommand(cChangeColor, itsShapeView, kCanUndo, kCausesChange,
gZeroVPt, !kBetterFeedbackDesired);
fColor = itsColor;
}
//----------------------------------------------------------------------------------------
// TRecolorCmd::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TRecolorCmd::DoIt() // Override
{
fShapeView->Focus();
/* fShapeDocument.EachShapeDo(RecolorShape); */
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->IsSelected())
{
shape->ReplaceColor(fColor);
fShapeView->InvalShape(shape);
}
shape->SetWasIsSelected();
}
}
//----------------------------------------------------------------------------------------
// TRecolorCmd::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TRecolorCmd::RedoIt() // Override
{
fShapeView->Focus();
fShapeView->Deselect();
/* fShapeDocument.EachShapeDo(RecolorShape); */
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->WasSelected())
{
shape->ReplaceColor(fColor);
fShapeView->InvalShape(shape);
}
shape->SetIsWasSelected();
}
}
//----------------------------------------------------------------------------------------
// TRecolorCmd::UndoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TRecolorCmd::UndoIt() // Override
{
fShapeView->Focus();
fShapeView->Deselect();
/* fShapeDocument.EachShapeDo(RecolorShape); */
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
if (shape->WasSelected())
{
shape->fColor = shape->fOldColor;
fShapeView->InvalShape(shape);
}
shape->SetIsWasSelected();
}
}
//========================================================================================
// CLASS TShapeReplaceCommand
//========================================================================================
#undef Inherited
#define Inherited TShapeCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeReplaceCommand, Inherited);
//----------------------------------------------------------------------------------------
// TShapeReplaceCommand Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeReplaceCommand::TShapeReplaceCommand()
{
}
//----------------------------------------------------------------------------------------
// TShapeReplaceCommand::IShapeReplaceCommand
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeReplaceCommand::IShapeReplaceCommand(CommandNumber itsCommandNumber,
TShapeView* itsShapeView,
const VPoint& theMouse,
Boolean betterFeedbackDesired)
{
this->IShapeCommand(itsCommandNumber, itsShapeView,
kCanUndo, kCausesChange,
theMouse, betterFeedbackDesired);
}
//----------------------------------------------------------------------------------------
// TShapeReplaceCommand::Commit
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeReplaceCommand::Commit() // Override
{
if (fShapeDocument->IsFiltering())
{
fShapeDocument->EachShapeDo(&HandleIt, (void*)fShapeDocument);
}
fShapeDocument->SetFiltering(false);
fShapeDocument->fReplaceCommand = NULL;
}
//----------------------------------------------------------------------------------------
// TShapeReplaceCommand::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeReplaceCommand::RedoIt() // Override
{
if (fShapeDocument->IsFiltering())
fShapeView->RestoreSelection();
fShapeDocument->fReplaceCommand = this;
}
//----------------------------------------------------------------------------------------
// TShapeReplaceCommand::UndoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeReplaceCommand::UndoIt() // Override
{
fShapeView->RestoreSelection();
fShapeDocument->fReplaceCommand = NULL;
fShapeDocument->SetFiltering(false);
}
//----------------------------------------------------------------------------------------
// TShapeReplaceCommand::EachNewShapeDo
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeReplaceCommand::EachNewShapeDo(DoToShapeType /*DoToShape*/, void* /*staticLink*/)
{
// Do nothing
}
//========================================================================================
// CLASS TShapeSketcher
//========================================================================================
#undef Inherited
#define Inherited TShapeReplaceCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeSketcher, Inherited);
//----------------------------------------------------------------------------------------
// TShapeSketcher Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeSketcher::TShapeSketcher()
{
fShape = NULL;
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::IShapeSketcher
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeSketcher::IShapeSketcher(TShapeView* itsShapeView,
TShape* protoShape,
const VPoint& theMouse,
Boolean constrain)
{
this->IShapeReplaceCommand(cNewShape, itsShapeView,
theMouse, gBetterFeedback);
fShape = protoShape;
fConstrainsMouse = constrain;
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::Free
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::Free() // Override
{
fShape = (TShape*)FreeIfObject(fShape);
Inherited::Free();
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::DoIt() // Override
{
fShape->SetSelected(true);
fShape->DoInitialState(fShapeView);
fShapeDocument->fReplaceCommand = this;
fShapeView->InvalShape(fShape);
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::UndoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::UndoIt() // Override
{
Inherited::UndoIt();
fShapeView->InvalShape(fShape);
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::RedoIt() // Override
{
fShapeView->Focus();
fShapeView->Deselect();
Inherited::RedoIt();
fShape->SetSelected(true);
fShapeView->InvalShape(fShape);
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::Commit
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::Commit() // Override
{
/* As a rule - Commit methods should not be allowed to Fail. This commit method is a bad
example in that a new shape is added to the document - this could actually cause this
Commit method to Fail.
*/
fShapeDocument->AddShape(fShape); // Add the shape to the list
// Set this field to NULL to prevent Free from freeing it
fShape = NULL;
Inherited::Commit();
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::EachNewShapeDo
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::EachNewShapeDo(DoToShapeType DoToShape, void* staticLink) // Override
{
DoToShape(fShape, staticLink);
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::TrackConstrain
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::TrackConstrain(TrackPhase /*aTrackPhase*/,
const VPoint& anchorPoint,
const VPoint& /*previousPoint*/,
VPoint& nextPoint,
Boolean /*mouseDidMove*/) // Override
{
long dh, dv, absDh, absDv, delta;
dh = nextPoint.h - anchorPoint.h;
dv = nextPoint.v - anchorPoint.v;
absDh = abs((int)dh);
absDv = abs((int)dv);
delta = Min(absDh, absDv);
if (dh < 0)
dh = - delta;
else
dh = delta;
if (dv < 0)
dv = - delta;
else
dv = delta;
nextPoint.h = anchorPoint.h + dh;
nextPoint.v = anchorPoint.v + dv;
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::TrackFeedback
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeSketcher::TrackFeedback(TrackPhase aTrackPhase,
const VPoint& anchorPoint,
const VPoint& previousPoint,
const VPoint& nextPoint,
Boolean mouseDidMove,
Boolean turnItOn) // Override
{
Inherited::TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint,
mouseDidMove, turnItOn);
if (mouseDidMove && fShape)
fShape->DrawOutline();
}
//----------------------------------------------------------------------------------------
// TShapeSketcher::TrackMouse
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
TTracker* TShapeSketcher::TrackMouse(TrackPhase aTrackPhase,
VPoint& anchorPoint,
VPoint& previousPoint,
VPoint& nextPoint,
Boolean mouseDidMove) // Override
{
TTracker* newTracker = Inherited::TrackMouse(aTrackPhase, anchorPoint, previousPoint,
nextPoint, mouseDidMove);
if (aTrackPhase == trackRelease) // create the new shape
{
Boolean bigEnough = false;
VPoint size;
size.h = nextPoint.h - anchorPoint.h;
size.v = nextPoint.v - anchorPoint.v;
if (abs((int)size.h) >= kMinWidth)
if (abs((int)size.v) >= kMinHeight)
bigEnough = true;
if (!bigEnough)
{
fShape = (TShape*)FreeIfObject(fShape);
newTracker = NULL;
}
}
else
{
VRect aVRect;
CRect r;
Pt2VRect(anchorPoint, nextPoint, aVRect);
VRectToRect(aVRect, r); // OK because we know the view's size is in QD dimensions
fShape->SetFrame(r);
}
return newTracker;
}
//========================================================================================
// CLASS TShapeCutCopyCommand
//========================================================================================
#undef Inherited
#define Inherited TShapeReplaceCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeCutCopyCommand, Inherited);
//----------------------------------------------------------------------------------------
// TShapeCutCopyCommand Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeCutCopyCommand::TShapeCutCopyCommand()
{
}
//----------------------------------------------------------------------------------------
// TShapeCutCopyCommand::IShapeCutCopyCommand
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeCutCopyCommand::IShapeCutCopyCommand(CommandNumber itsCommandNumber,
TShapeView* itsShapeView)
{
this->IShapeReplaceCommand(itsCommandNumber, itsShapeView, gZeroVPt, !kBetterFeedbackDesired);
fChangesClipboard = true;
fCausesChange = (itsCommandNumber == cCut);
}
//----------------------------------------------------------------------------------------
// TShapeCutCopyCommand::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeCutCopyCommand::DoIt() // Override
{
TShapeView* clipShapeView;
MAVolatileInit(TShapeDocument*, clipDoc, NULL);
fShapeView->SaveSelection(fIdentifier == cCut); // don't invalidate if it's just COPY
clipDoc = new TShapeDocument;
clipDoc->IShapeDocument(NULL);
FailInfo fi;
Try(fi)
{
short count;
CRect outline;
fShapeDocument->SurveyShapes(true, count, outline);
clipShapeView = new TShapeView;
clipShapeView->IShapeView(clipDoc, true);
// Set fShapeView since the doc will NOT be told to DoMakeViews
clipDoc->fShapeView = clipShapeView;
if (fIdentifier == cCut)
fShapeView->Focus();
/* fShapeDocument.EachShapeDo(CopyToClip); */
{
CShapeIterator iter(fShapeDocument->GetShapeList());
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
if (shape->IsSelected())
{
TShape* aNewShape = (TShape*)shape->Clone();
aNewShape->SetSelected(false);
aNewShape->SetWasSelected(false);
CRect r;
shape->GetFrame(r);
OffsetRect(r, gClipMargin.h - outline.left, gClipMargin.v - outline.top);
aNewShape->SetFrame(r);
clipDoc->AddShape(aNewShape);
}
}
clipShapeView->AdjustFrame();
// Make sure the Cut left us with enough memory to continue.
FailSpaceIsLow();
fi.Success();
}
else
{
FreeIfObject(clipDoc);
fi.ReSignal();
}
this->ClaimClipboard(clipShapeView);
fShapeDocument->SetFiltering(fIdentifier != cCopy);
fShapeDocument->fReplaceCommand = this;
}
void TShapeCutCopyCommand::RedoIt() // Override
{
fShapeDocument->SetFiltering(fIdentifier != cCopy);
Inherited::RedoIt();
}
//========================================================================================
// CLASS TShapeClearCommand
//========================================================================================
#undef Inherited
#define Inherited TShapeReplaceCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapeClearCommand, Inherited);
//----------------------------------------------------------------------------------------
// TShapeClearCommand Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapeClearCommand::TShapeClearCommand()
{
}
//----------------------------------------------------------------------------------------
// TShapeClearCommand::IShapeClearCommand
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapeClearCommand::IShapeClearCommand(TShapeView* itsShapeView)
{
this->IShapeReplaceCommand(cClear, itsShapeView, gZeroVPt, !kBetterFeedbackDesired);
}
//----------------------------------------------------------------------------------------
// TShapeClearCommand::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeClearCommand::DoIt() // Override
{
fShapeView->SaveSelection(true); // TRUE means invalidate the shapes
fShapeDocument->SetFiltering(true);
fShapeDocument->fReplaceCommand = this;
}
//----------------------------------------------------------------------------------------
// TShapeClearCommand::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapeClearCommand::RedoIt() // Override
{
fShapeDocument->SetFiltering(true);
Inherited::RedoIt();
}
//========================================================================================
// CLASS TShapePasteCommand
//========================================================================================
#undef Inherited
#define Inherited TShapeReplaceCommand
#pragma segment ASelCommand
MA_DEFINE_CLASS_M1(TShapePasteCommand, Inherited);
//----------------------------------------------------------------------------------------
// TShapePasteCommand Constructor
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
TShapePasteCommand::TShapePasteCommand()
{
fPasteList = NULL;
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::IShapePasteCommand
//----------------------------------------------------------------------------------------
#pragma segment ASelCommand
void TShapePasteCommand::IShapePasteCommand(TShapeView* itsShapeView)
{
this->IShapeReplaceCommand(cPaste, itsShapeView, gZeroVPt, !kBetterFeedbackDesired);
FailInfo fi;
Try(fi)
{
fPasteList = new TShapeList;
fPasteList->IList();
#if qDebug
fPasteList->SetEltType("TShape");
#endif
fi.Success();
}
else
{
this->Free();
fi.ReSignal();
}
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::Free
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::Free() // Override
{
fPasteList = (TShapeList*)FreeIfObject(fPasteList);
Inherited::Free();
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::Commit
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::Commit() // Override
{
if (gPasteReplacesSelection)
Inherited::Commit(); // Deletes old selectees from the document
/* The following loop transfers shapes from fPasteList to the document's
shape list, in such a way that fPasteList is shrunk while the
document's shape list is grown. This helps prevent running out
of memory when Commiting a Paste command.
*/
// As a rule - Commit methods should not be allowed to fail. This Commit method is a
// bad example in that a new shape is added to the document - this could actually cause
// this Commit method to fail.
TShape* theShape = (TShape*)fPasteList->First();
while (theShape)
{
fPasteList->Delete(theShape);
fShapeDocument->AddShape(theShape);
theShape = (TShape*)fPasteList->First();
}
fShapeDocument->fReplaceCommand = NULL;
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::DoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::DoIt() // Override
{
CPoint whereToPaste;
TView* clipView = gClipboardMgr->fClipView;
FailNonObject(clipView);
#if qDebug
if (!clipView->DescendsFrom(TShapeView::GetClassDescStatic()))
ProgramBreak("Attempt to paste a non-TShapeView clipboard");
#endif
// The next section figures out where the pasted shapes should be placed in the view.
// Lovely, isn't it?
if (gPasteReplacesSelection)
{
// If we're replacing shapes, then paste the new shapes starting at the top-left
// corner of the replaced shapes. Otherwise, start at the last clicked point in
// the view.
short noOfShapes;
CRect extent;
fShapeDocument->SurveyShapes(true, noOfShapes, extent);
if (noOfShapes > 0)
whereToPaste = extent[topLeft];
else
whereToPaste = fShapeView->fClickPt;
}
else
{
VRect scrollerExtent;
fShapeView->fSuperView->GetExtent(scrollerExtent);
for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
{
long t; // temp var
t = (scrollerExtent[botRight][vhs] + scrollerExtent[topLeft][vhs] -
clipView->fSize[vhs]) / 2;
whereToPaste[vhs] = (short)Max(scrollerExtent[topLeft][vhs], t);
}
}
SubPt(gClipMargin, whereToPaste);
fShapeView->SaveSelection(gPasteReplacesSelection);
fShapeView->Deselect();
if (clipView->GivePasteData(NULL, kShapeClipType) > 0)
PasteShapes(whereToPaste);
else if (clipView->GivePasteData(NULL, 'PICT') > 0)
PastePict(whereToPaste);
else if (clipView->GivePasteData(NULL, 'TEXT') > 0)
PasteText(whereToPaste);
fShapeDocument->SetFiltering(gPasteReplacesSelection);
fShapeDocument->fReplaceCommand = this;
fShapeView->AdjustFrame(); // Make sure all the Pasted shapes can be seen
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::UndoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::UndoIt() // Override
{
Inherited::UndoIt();
this->EachNewShapeDo(&BeInvalidated, (void*)fShapeView);
fShapeView->Focus();
fShapeDocument->SetFiltering(false);
fShapeView->AdjustFrame();
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::RedoIt
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::RedoIt() // Override
{
fShapeView->Focus();
fShapeView->Deselect();
// Invalidate all the newly-added shapes
this->EachNewShapeDo(&BeSelected, (void*)fShapeView);
fShapeDocument->SetFiltering(gPasteReplacesSelection);
Inherited::RedoIt();
fShapeView->AdjustFrame(); // Make sure size reflects the Paste
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::EachNewShapeDo
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::EachNewShapeDo(DoToShapeType DoToShape, void* staticLink) // Override
{
CShapeIterator iter(fPasteList);
for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
{
DoToShape(shape, staticLink);
}
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::PasteShapes
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::PasteShapes(CPoint whereToPaste)
{
#if qDebug
if (!gClipboardMgr->fClipView->DescendsFrom(TShapeView::GetClassDescStatic()))
ProgramBreak("Attempt to paste a non-TShapeView clipboard");
#endif
TShapeDocument* clipDoc = ((TShapeView*)gClipboardMgr->fClipView)->fShapeDocument;
/* clipDoc.EachShapeDo(PasteShape); */
CShapeIterator iter(clipDoc->GetShapeList());
for (TShape* clipShape = iter.FirstShape(); iter.More(); clipShape = iter.NextShape())
{
TShape* aShape = (TShape*)clipShape->Clone();
aShape->SetSelected(true);
aShape->SetWasSelected(true);
CRect extent;
aShape->GetFrame(extent);
OffsetRect(extent, whereToPaste.h, whereToPaste.v);
aShape->SetFrame(extent);
fPasteList->InsertLast(aShape);
aShape->BeInView(fShapeView);
fShapeView->InvalShape(aShape);
}
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::PastePict
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::PastePict(CPoint whereToPaste)
{
MAVolatileInit(PicHandle, picture, NULL);
FailInfo fi;
Try(fi)
{
picture = (PicHandle)NewPermHandle(0);
FailSpaceIsLow();
long result = gClipboardMgr->fClipView->GivePasteData((Handle)picture, 'PICT');
if (result < 0) FailOSErr((OSErr)result);
// Read the shapes from the clipboard and add them to the document
CRect extent((**picture).picFrame);
OffsetRect(extent, whereToPaste.h, whereToPaste.v);
TPictShape* pictShape = new TPictShape;
pictShape->IPictShape(extent, 5);
////pictShape->DoInitialState(this);
pictShape->SetPicture(picture);
pictShape->BeInView(fShapeView);
fPasteList->InsertLast(pictShape);
fShapeView->InvalShape(pictShape);
fi.Success();
}
else // Recover
{
DisposeIfHandle((Handle)picture);
fi.ReSignal();
}
}
//----------------------------------------------------------------------------------------
// TShapePasteCommand::PasteText
//----------------------------------------------------------------------------------------
#pragma segment ADoCommand
void TShapePasteCommand::PasteText(CPoint whereToPaste)
{
MAVolatileInit(Handle, text, NULL);
FailInfo fi;
Try(fi)
{
text = NewPermHandle(0);
FailSpaceIsLow();
long result = gClipboardMgr->fClipView->GivePasteData(text, 'TEXT');
if (result < 0) FailOSErr((OSErr)result);
// Read the shapes from the clipboard and add them to the document
CRect extent(20, 20, 180, 180);
OffsetRect(extent, whereToPaste.h, whereToPaste.v);
TTextShape* textShape = new TTextShape;
textShape->ITextShape(extent, 4);
////textShape->DoInitialState(this);
textShape->SetText(text);
textShape->BeInView(fShapeView);
fPasteList->InsertLast(textShape);
fShapeView->InvalShape(textShape);
fi.Success();
}
else // Recover
{
DisposeIfHandle(text);
fi.ReSignal();
}
DisposeIfHandle(text);
}